package arcademis.concreteComponents;

import arcademis.*;

/**
 * This class is the implementation of a <CODE>Connector</CODE> component that does
 * not block
 * the application during the process of connection set up. If the connection cannot
 * be imediately established, this component keeps trying to set it up.
 */
public class AssynchronousConnector extends Connector implements Runnable {

	private Channel ch = null;
	private ServiceHandler sh = null;
	private Epid epid = null;
	private boolean finished = false;

	/**
	 * This method starts a new thread to carry on the process of connection set up.
	 * @param h the service handler that will be used to process the channel after
	 * it has been generated by the connector.
	 * @param epid the location of the acceptor that will be contacted in order to
	 * generate a channel with this connector.
	 * @throws NetworkException in the case some error takes place in the
	 * transport layer.
	 */
	public void connect(ServiceHandler sh, Epid epid) throws NetworkException {
		this.sh = sh;
		this.epid = epid;
		Thread t = new Thread(this);
		t.start();
	}

	/**
	 * This method keeps trying to establish the connection if it cannot be imediately
	 * set up. Each new attempt takes place in regular intervals of 1 second.
	 */
	public void run() {
		while(finished == false) {
			try {
				tryConnectionEstablishment();
			} catch(NetworkException ne) {
				try {
					Thread.sleep(1000);
				}catch(InterruptedException ie) {}
			}
		}
	}

	private void tryConnectionEstablishment() throws NetworkException {
System.out.println("AssynchConnector: tryConnection");
		if(ch == null)
			ch = OrbAccessor.getChannel();
		ch.connect(epid);
		finished = true;
		sh.open(ch);
	}
}